package org.spidermesh.meshlog.util;

import org.spidermesh.meshlog.model.LogInfo;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @PackageName:org.spidermesh.meshlog.core
 * @ClassName:QueryUtil
 * @Description:
 * @Author:hw
 * @Date:2020-12-9 17:48
 */
@Component
public class QueryUtil {
    @PersistenceContext
    private EntityManager entityManager;
    private StringBuffer queryString=new StringBuffer();
    private String table;
    private StringBuffer sqlheader=new StringBuffer();
    private String joiner;

    public QueryUtil() {
        this.table = "t_meshlog";
        this.joiner = "AND";
        this.sqlheader.append("SELECT * FROM")
                .append(" ")
                .append(table)
                .append(" ")
                .append("WHERE")
                .append(" ");
    }

    public QueryUtil refresh(String table,String sqlheader,String joiner){
        this.joiner=joiner;
        int len=this.sqlheader.length();
        this.sqlheader.delete(0,len);
        this.sqlheader.append(sqlheader)
                .append(" ")
                .append(table)
                .append(" ")
                .append("WHERE")
                .append(" ");
        return this;
    }

    public <T extends LogInfo> QueryUtil paramBuilder(T logInfo) {
        Class clazz = logInfo.getClass();
        Field[] fields = clazz.getFields();
        String querybody=Arrays.stream(fields).map(
                f -> {
                    StringBuilder tmpstr=new StringBuilder();
                    f.setAccessible(true);
                    try {
                        if (null!=f.get(logInfo)){
                            tmpstr.append(f.getName())
                            .append("=")
                            .append(f.get(logInfo).toString());
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        return "";
                    }
                    return tmpstr;
                }
        ).collect(Collectors.joining(" "+joiner+" "));

        this.queryString.append(this.sqlheader).append(querybody);
        return this;
    }

    public QueryUtil rangeBuilder(String param,String lower,String upper,Boolean reverse){
        this.queryString.append(this.sqlheader)
                .append(reverse?"NOT ":"")
                .append(param)
                .append("BETWEEN")
                .append(" ")
                .append(lower)
                .append(" AND ")
                .append(lower);
        return this;
    }

    public List<LogInfo> query() {
        return entityManager.createNativeQuery(this.queryString.toString()).getResultList();
    }
    public int update() {
        return entityManager.createQuery(this.queryString.toString()).executeUpdate();
    }

}
